package com.project.core.util;


import com.project.business.entity.constant.FileType;
import com.common.exception.ErrCode;
import com.common.exception.SeException;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.DecimalFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FileUtils {

    /**
     * 定义非法字符正则表达式
     */
    private static final String ILLEGAL_CHARACTERS_REGEX = "[\\\\/:*?\"<>|]";

    /**
     * 常见图片格式集合
     */
    public static String imageStrArr = "png,jpg,jpeg,svg,gif,";

    /**
     * 常见视频格式集合
     */
    public static String videoStrArr = "wmv,asf,asx,rm,rmvb,mp4,3gp,mov,m4v,avi,dat,mkv,flv,vob,mpg,mpeg,mpe,";

    /**
     * 常见音频格式集合
     */
    public static String audioStrArr = "mp3,wma,aac,ra,ogg,vqf,amr,ape,flac,m4a,mid,";

    /**
     * 常见压缩包格式集合
     */
    public static String zipStrArr = "tar,gz,rar,zip,7z,";

    /**
     * 常见文件类型格式集合
     */
    public static String fileStrArr = "doc,docx,xls,xlsx,ppt,pptx,wps," +
            "et,xlt,xlsm,xltx,xltm,csv,txt,rtf,dot,wpt,dotx,docm,dotm," +
            "pptm,pptsm,pps,potx,potm,dpt,dps," +
            "psd,ai,indd,u3d,prc,dwg,dwt,dxf,dwf,dst," +
            "mpp,vsd,xps,ps,eps,prn," +
            "db,sql,";

    /**
     * pdf
     */
    public static String pdfStr = "pdf";

    /**
     * 获取文件的contentType
     *
     * @param fileName 文件名
     * @return contentType
     */
    public static String getContentType(String fileName) {
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        String result;
        fileType = fileType.toLowerCase();
        if (fileType.endsWith(".png")) {
            result = "image/png";
        } else if (fileType.endsWith(".gif")) {
            result = "image/gif";
        } else if (fileType.endsWith(".jpg") || fileType.endsWith(".jpeg")) {
            result = "image/jpeg";
        } else if (fileType.endsWith(".svg")) {
            result = "image/svg+xml";
        }
//        else if (fileType.endsWith(".doc")) {
//            result = "application/msword";
//        } else if (fileType.endsWith(".xls")) {
//            result = "application/x-excel";
//        } else if (fileType.endsWith(".zip")) {
//            result = "application/zip";
//        }
        else if (fileType.endsWith(".pdf")) {
            result = "application/pdf";
        } else {
            result = "application/octet-stream";
        }
        return result;
    }

    /**
     * 处理文件大小
     */
    public static String getFileSizeDescription(long size) {
        StringBuilder bytes = new StringBuilder();
        DecimalFormat format = new DecimalFormat("###.0");
        if (size >= 1024 * 1024 * 1024) {
            double i = (size / (1024.0 * 1024.0 * 1024.0));
            bytes.append(format.format(i)).append("GB");
        } else if (size >= 1024 * 1024) {
            double i = (size / (1024.0 * 1024.0));
            bytes.append(format.format(i)).append("MB");
        } else if (size >= 1024) {
            double i = (size / (1024.0));
            bytes.append(format.format(i)).append("KB");
        } else {
            if (size <= 0) {
                bytes.append("0B");
            } else {
                bytes.append((int) size).append("B");
            }
        }
        return bytes.toString();
    }

    /**
     * 输入流 输出到 输出流
     *
     * @param inputStream 输入流
     */
    public static ByteArrayOutputStream byteArrayOutputStream(InputStream inputStream) throws IOException {
        if (inputStream == null) {
            return null;
        }
        byte[] bytes = new byte[8192];
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DataInputStream dataInputStream = new DataInputStream(inputStream);
        int n;
        while ((n = dataInputStream.read(bytes)) != -1) {
            byteArrayOutputStream.write(bytes, 0, n);
        }
        return byteArrayOutputStream;
    }

    /**
     * 保存inputStream到文件
     *
     * @param inputStream inputStream
     * @param filePath    文件全路径
     * @return File
     */
    public static File saveFile(InputStream inputStream, String filePath) {
        File file = new File(filePath);
        return save(inputStream, file);
    }

    /**
     * 保存inputStream到文件
     *
     * @param inputStream inputStream
     * @param file        file
     * @return File
     */
    public static File saveFile(InputStream inputStream, File file) {
        return save(inputStream, file);
    }

    private static File save(InputStream inputStream, File file) {
        OutputStream outputStream = null;
        try {
            outputStream = Files.newOutputStream(file.toPath());

            // 保存文件
            Files.copy(inputStream, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (Exception e) {
            throw new SeException(ErrCode.System_Error, "文件上传失败！");
        } finally {
            try {
                if (null != inputStream) {
                    inputStream.close();
                }
                if (null != outputStream) {
                    outputStream.close();
                }
            } catch (Exception e) {
                //
            }
        }
        return file;
    }

    /**
     * 通过文件名称获取自定义文件分类
     *
     * @param fileName 文件名称
     * @return FileType
     */
    public static FileType getFileType(String fileName) {
        // 获取到doc, pdf等文件类型
        String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
        // 转换小写
        fileType = fileType.toLowerCase();
        if (imageStrArr.contains(fileType + ",")) {
            return FileType.Pic;
        } else if (videoStrArr.contains(fileType + ",")) {
            return FileType.Video;
        } else if (audioStrArr.contains(fileType + ",")) {
            return FileType.Audio;
        } else if (zipStrArr.contains(fileType + ",")) {
            return FileType.Zip;
        } else if (fileStrArr.contains(fileType + ",")) {
            return FileType.File;
        } else if (pdfStr.equalsIgnoreCase(fileType)) {
            return FileType.Pdf;
        } else {
            return FileType.Other;
        }
    }

    /**
     * 获取文件的后缀名。
     *
     * @param name 文件的完整名称，包括后缀名。
     * @return 文件的后缀名。如果文件名中没有包含后缀名，则返回当前字符串
     */
    public static String getFileSuffix(String name) {
        return name.substring(name.lastIndexOf(".") + 1);
    }

    /**
     * 文件名是否合法
     *
     * @param name 文件名
     * @return 是否合法
     */
    public static boolean nameIsLegal(String name) {
        // 创建Pattern对象
        Pattern pattern = Pattern.compile(ILLEGAL_CHARACTERS_REGEX);

        // 创建Matcher对象用于匹配输入的字符串
        Matcher matcher = pattern.matcher(name);

        // 检查是否存在非法字符
        return matcher.find();
    }
}
